﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SCRUM.Core.DAO;

namespace SCRUM.Core.BusinessObjects
{
    /// <summary>
    /// Represents comment, comments may be used for any type of entity, 
    /// Comments are grouped in threads
    /// </summary>
    public class Comment
    {
        /// <summary>
        /// Unique database representation of comment
        /// </summary>
        public int ID { get; set; }

        /// <summary>
        /// Text of comment
        /// </summary>
        public string Text { get; set; }
        
        /// <summary>
        /// Date of creation
        /// </summary>
        public DateTime Date { get; set; }
        
        /// <summary>
        /// Login of user that created comment
        /// </summary>
        private string userLogin { get; set; }
        
        /// <summary>
        /// Private representation of user that created comment for lazy loading
        /// </summary>
        private User user;

        /// <summary>
        /// Lazily loaded User that created comment
        /// </summary>
        public User User
        {
            get
            {
                // Lazy loading
                if (this.user == null)
                {
                    this.user = SCRUM.Core.MembershipProviders.MembershipProviderFactory.MembershipProvider.GetUser(userLogin, true) as User;
                }
                return this.user;
            }
            set
            {
                this.user = value;
            }
        }

        /// <summary>
        /// Comments may contain subcomments
        /// </summary>
        private List<Comment> subComments;

        /// <summary>
        /// Comments on comments
        /// </summary>
        public List<Comment> SubComments
        {
            get
            {
                // Lazy loading
                if (this.subComments == null)
                {
                    this.subComments = DAOComment.GetSubCommentsForComment(ID);
                }
                return this.subComments;
            }
            set
            {
                this.subComments = value;
            }
        }

        /// <summary>
        /// Comment must be in some thread. Makes loading easier
        /// </summary>
        private Thread inThread;

        /// <summary>
        /// Thread that comment is in
        /// </summary>
        public Thread InThread
        {
            get
            {
                // Lazy loading
                if (this.inThread == null)
                {
                    this.inThread = DAOComment.GetThreadByID(this.inThread.ID);
                }
                return this.inThread;
            }
            set
            {
                this.inThread = value;
            }
        }

        /// <summary>
        /// Default constructor
        /// </summary>
        public Comment()
        { 
        }

        /// <summary>
        /// Constructor with required parameters
        /// </summary>
        /// <param name="ID">ID of comment</param>
        /// <param name="text">Text of comment</param>
        /// <param name="date">Date of creation</param>
        /// <param name="userLogin">Login of user that created comment</param>
        /// <param name="inThread">Thread of comment</param>
        public Comment(int ID, string text, DateTime date, string userLogin, Thread inThread)
        {
            this.ID = ID;
            this.Text = text;
            this.Date = date;
            this.userLogin = userLogin;
            this.inThread = inThread;
        }

        /// <summary>
        /// Overriden toString that concatinates comment details
        /// </summary>
        /// <returns>50 character representation of comment</returns>
        public override string ToString()
        {
            String result = this.User.FullName + " ";
            result += this.Date.ToShortDateString() + " :";
            result += this.Text;
            if (result.Length >= 50)
            {
                return result.Substring(0, 50);
            }
            else
                return result;
        }
    }
}
